package com.homework.HomeAcount.realm;

import java.util.ArrayList;
import java.util.List;

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.LockedAccountException;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource;
import org.springframework.beans.factory.annotation.Autowired;

import com.homework.HomeAcount.entity.CurrentUser;
import com.homework.HomeAcount.entity.Menu;
import com.homework.HomeAcount.entity.Permission;
import com.homework.HomeAcount.entity.Role;
import com.homework.HomeAcount.entity.User;
import com.homework.HomeAcount.service.MenuService;
import com.homework.HomeAcount.service.PermissionService;
import com.homework.HomeAcount.service.RoleService;
import com.homework.HomeAcount.service.UserService;
/**
 * 
 * Project Name:HomeAcount 
 * @author gk
 * Shiro自定义的Realm(域)
 * Date:2015年12月1日下午7:04:23 
 * Copyright (c) 2015, gkaigk@126.com All Rights Reserved. 
 * @Version 1.0
 */
public class UserRealm extends AuthorizingRealm {

	@Autowired
	private UserService userService;
	
	@Autowired
	private MenuService menuService;
	
	@Autowired
	private PermissionService permissionService;
	
	@Autowired
	private RoleService roleService;

	@Override
	protected AuthorizationInfo doGetAuthorizationInfo(
			PrincipalCollection principalCollection) {
		CurrentUser currentUser = (CurrentUser) principalCollection.getPrimaryPrincipal();
		List<Role> roles = roleService.getRolesByUserId(currentUser.getId());
		List<Permission> permissions = permissionService.getPermissionsByUserId(currentUser.getId());
		SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();
		simpleAuthorizationInfo.addRoles(this.getRoleStrings(roles));
		simpleAuthorizationInfo.addStringPermissions(this.getPermissionStrings(permissions));
		return simpleAuthorizationInfo;
	}

	@Override
	protected AuthenticationInfo doGetAuthenticationInfo(
			AuthenticationToken token) throws AuthenticationException {
		String userName = (String) token.getPrincipal();
		User user = userService.findUserByUserName(userName);
		if (null == user) {
			throw new UnknownAccountException();// 没找到帐号
		}

		if ("1".equals(user.getLocked())) {
			throw new LockedAccountException(); // 帐号锁定
		}
		CurrentUser currentUser = new CurrentUser();
		currentUser.setId(user.getId());
		currentUser.setUsername(user.getUsername());
		currentUser.setUsercode(user.getUserCode());
		currentUser.setPassword(user.getPassword());
		currentUser.setSalt(user.getSalt());
		currentUser.setLocked(user.getLocked());
		
		List<Menu> menus = menuService.findMenusByUserId(user.getId());
		menus = getUserMenus(menus);
		currentUser.setMenus(menus);
		
		SimpleAuthenticationInfo simpleAuthenticationInfo = new SimpleAuthenticationInfo(
				currentUser, user.getPassword(),
				ByteSource.Util.bytes(currentUser.getUsername() + currentUser.getSalt()),
				this.getName());
		return simpleAuthenticationInfo;
	}
	
	private List<String> getRoleStrings(List<Role> roles) {
		if(null == roles || roles.size() < 1) {
			return null;
		}
		List<String> roleStrings = new ArrayList<String>();
		for(Role role : roles) {
			roleStrings.add(role.getName());
		}
		return roleStrings.size() > 0? roleStrings : null;
	}
	
	private List<String> getPermissionStrings(List<Permission> permissions) {
		if(null == permissions || permissions.size() < 1) {
			return null;
		}
		List<String> permissionStrings = new ArrayList<String>();
		for(Permission permission : permissions) {
			permissionStrings.add(permission.getPercode());
		}
		return permissionStrings.size() > 0? permissionStrings : null;
	}
	
	private List<Menu> getUserMenus(List<Menu> menus) {
		if(null != menus && menus.size() > 0) {
			List<Menu> allMenus = new ArrayList<Menu>();
			for(Menu menu : menus) {
				List<Menu> subMenus = menuService.findSubMenusByParentId(menu.getId());
//				subMenus = null != subMenus && subMenus.size() > 0? subMenus : null;
				menu.setSubMenus(subMenus);
				allMenus.add(menu);
			}
			return allMenus;
		}
		return null;
	}
	
	//清除缓存
	public void clearCached() {
		PrincipalCollection principals = SecurityUtils.getSubject().getPrincipals();
		super.clearCache(principals);
	}
}